package com.hmall.util;


import com.hdmall.business.common.common.ServerResponse;
import com.hdmall.business.common.util.AgentUtil;
import com.hmall.config.RedisCacheConfiguration;
import com.hmall.mapper.SysUserMapper;
import com.hmall.model.SysUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.PostConstruct;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/*生成token*/
//@Component
public class TokenUtil {

//    @Autowired
//    SysUserMapper userMapper;

   // private Logger logger = LoggerFactory.getLogger(this.getClass());

    /*签名秘钥*/
    public static final String SECRET = "huading";

    public static TokenUtil tokenUtil;

//
//   static {
//       RedisCacheConfiguration   redisCacheConfiguration = new RedisCacheConfiguration();
//       JedisPool jedisPool = redisCacheConfiguration.redisPoolFactory();
//   }
////
//    @PostConstruct
//    public void init(){
//        tokenUtil = this;
//        tokenUtil.jedisPool = this.jedisPool;
//    }

    /*生成token
     *
     * id:编号
     * issuser:JWT的签发者，是否使用是可选的
     * subject:JWT所面向的用户，是否使用时可选的
     *ttlMillis:签发时间
     *
     */
    public static String createJwtToken(String id){
        String issuser = "www.huading.com";
        String subject = "huading@xxx.com";
        long ttlMillis = System.currentTimeMillis();
        return createJwtToken(id, issuser, subject, ttlMillis);
    }

    public static String createJwtToken(String id, String issuser, String subject, long ttlMillis ){

        //签名算法,对token进行签名
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //生成签发时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //通过密钥签名JWT
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id)
                .setIssuedAt(now)
                .setSubject(subject)
                .setIssuer(issuser)
                .signWith(signatureAlgorithm,signingKey);

        //if it has been specified, let's add the expiration
        if(ttlMillis >= 0){
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        // Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();
    }
    // 根据jwt加密获得claims 要求
    public static Claims parseJWT(String jwt){
        // This line will throw an exception if it is not a signed JWS (as expected)
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
                .parseClaimsJws(jwt).getBody();
        return claims;
    }

//    //根据token返回user，user里面只是登陆的时候获得的一部分用来验证的信息
//    public ServerResponse<SysUser>  tokenToUser(Jedis jedis, String token) throws Exception{
//
//        //token转换成user之前先判断token是否有效，是否失效
//
//
//        Claims claims;
//        try {
//            claims = TokenUtil.parseJWT(token);
//        }catch (Exception e){
//            // e.printStackTrace();
//            return ServerResponse.createByStatus(11, "无该用户，请重新登录");
//        }
//        String agentUserName = claims.getId();
//
//
//        String str[] = AgentUtil.deleteAgentUserName(agentUserName).getData().split(":");
//        String agent = str[0];
//        String username = str[1];
//        //每次需要获得用户信息从redis中取
//
//        //如果用户名无法得到
//        if(username == null || username.equals("")){
//            return ServerResponse.createByStatus(11, "无该用户，请重新登录");
//        }
//
//        //获取到用户名之后token已经失效
//        String nowToken = jedis.get(agent + username);
//
//        if(nowToken == null){
//            return ServerResponse.createByStatus(12, "用户已失效，请重新登录");
//        }
//        if(nowToken.equals(token) == false){
//            return ServerResponse.createByStatus(12, "用户已失效,请重新登录");
//        }
//
//        String key = agent + username + "REDIS_USER";
//        //如果存在键值，获取value值
//        //redis中key值为userName+"REDIS_USER"的value
//        String value = jedis.get(key);
//        SysUser user = new SysUser();
//
//        if(username != null) {
//            user = DataFomateUtil.stringToSysUser(value);
//        }
//
//
//        return ServerResponse.createBySuccess(user);
//
//    }

//    //做测试
//    //根据token返回user，user里面只是登陆的时候获得的一部分用来验证的信息
//    @PostConstruct
    public  ServerResponse<SysUser>  tokenToUser(JedisPool jedisPool, String token) throws Exception {


        //JedisPool jedisPool = new JedisPool();
        //token转换成user之前先判断token是否有效，是否失效

        Jedis jedis = jedisPool.getResource();

        Claims claims;
        try {
            claims = TokenUtil.parseJWT(token);
        } catch (Exception e) {
            return ServerResponse.createByStatus(11, "无该用户，请重新登录");
        }
        String agentUserName = claims.getId();


        String str[] = AgentUtil.deleteAgentUserName(agentUserName).getData().split(":");
        String agent = str[0];
        String username = str[1];
        //每次需要获得用户信息从redis中取

        //如果用户名无法得到
        if (username == null || "".equals(username)) {
            return ServerResponse.createByStatus(11, "无该用户，请重新登录");
        }

        //获取到用户名之后token已经失效

        String nowToken = jedis.get(agent + username);
        if (nowToken == null) {
            return ServerResponse.createByStatus(12, "用户已失效，请重新登录");
        }
        if (nowToken.equals(token) == false) {
            return ServerResponse.createByStatus(12, "用户已失效,请重新登录");
        }

        String key = agent + username + "REDIS_USER";
        //如果存在键值，获取value值
        //redis中key值为userName+"REDIS_USER"的value
        String value = jedis.get(key);

        jedis.close();
        SysUser user = new SysUser();

        if (username != null) {
            user = DataFomateUtil.stringToSysUser(value);
        }
//
//
        return ServerResponse.createBySuccess(user);
//
//    }

    }
        public static void main (String[]args){
            System.out.println(TokenUtil.createJwtToken("admin"));
        }
}
